﻿using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using System;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Tests.Integration.Instruments
{
    public abstract class VSPackageTestAutomaterBase<TPackage>
        where TPackage : Package
    {
        private WindowPaneManager<TPackage> windowPaneManager;


        protected AssertionHelper<TPackage> Assert { get; private set; }


        public TestContext TestContext { get; set; }


        protected VSPackageTestAutomaterBase()
        {
            Assert = new AssertionHelper<TPackage>();
            windowPaneManager = new WindowPaneManager<TPackage>();
        }


        protected virtual void OpenSolution(string path)
        {
            SolutionManager.OpenSolution(Path.GetFullPath(path));
        }

        protected virtual void SelectSolutionItem(params string[] names)
        {
            SolutionManager.SelectProjects(names);
        }

        protected virtual void ExecuteCommand(Guid menuGroupGuid, int commandId)
        {
            var executor = new CommandExecutor(menuGroupGuid, commandId);
            executor.Execute();
        }

        protected virtual void ExecuteCommand(Guid menuGroupGuid, int commandId, params UIControlAction [] actions)
        {
            var executor = new CommandExecutor(menuGroupGuid, commandId);
            foreach (var action in actions)
            {
                executor.UIControlActions.Add(action);
            }
            executor.Execute();
        }

        protected virtual IWindowPaneWrapper GetWindow<TWindowPane>()
            where TWindowPane : ToolWindowPane
        {
            return windowPaneManager.Get<TWindowPane>();
        }

        protected virtual void RunOnUIThread(Action action)
        {
            UIThreadInvoker.Invoke((Action)delegate
            {
                try
                {
                    action();
                }
                catch (Exception ex)
                {
                    TestContext.WriteLine(ex.GetType().FullName);
                    TestContext.WriteLine(ex.Message);
                    TestContext.WriteLine(ex.StackTrace);
                    Assert.Fail();
                }
            });
        }
    }
}
